<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,initial-scale=1"/>
        <link rel="stylesheet" type="text/css" href="/chat/css/style.css?v=1">
        <style type="text/css">
            .avatar{
                width:14vw;height:14vw;border-radius: 50%;overflow: hidden;margin-left: 2vw;text-align: center;background-size: 100% auto;
            };
        </style>
    </head>
    <body>
        <div id="app" v-cloak>
            <header class="nav">
                <i class="iconfont icon-return" @click="onBack"></i>
                <p>{$to_user['nickname']|default=''}</p>
            </header>
            <main class="content" id="content">
                <ul id="ul">
                    <template v-for="(item, i) in msgList">
                        <template v-if="msgList.length == 1 || i==0">
                            <li :class="[item.is_hidden ? 'hidden':'']">
                                <p>{{timeStr(item.time)}}</p>
                            </li>
                        </template>
                        <template v-else>
                            <template v-if="item.time - msgList[i-1]['time'] >= 60">
                                <li :class="[item.is_hidden ? 'hidden':'']">
                                    <p>{{timeStr(item.time)}}</p>
                                </li>
                            </template>
                        </template>
                        <template v-if="item.from_uid == to_uid">
                            <li :class="['left', item.is_hidden ? 'hidden':'']">
                                <div class="avatar" :style="{backgroundImage:'url('+to_user.avatar+')',backgroundSize:'100% auto'}"></div>
                                <template v-if="item.msg_type == 'text'">
                                    <span>{{item.content}}</span>
                                </template>
                                <template v-else="item.msg_type == 'image'">
                                    <img :src="item.content" class="img" @click="previewImage(i)" :data-i="i" />
                                </template>
                            </li>
                        </template>
                        <template v-else>
                            <li :class="['right', item.is_hidden ? 'hidden':'']" @click="rightMsgClick(i, $event)">
                                <template v-if="item.msg_type == 'text'">
                                    <span>{{item.content}}</span>
                                </template>
                                <template v-else="item.msg_type == 'image'">
                                    <img :src="item.content" class="img" @click="previewImage(i)" :data-i="i" />
                                </template>
                                <div class="avatar" :style="{backgroundImage:'url('+user.avatar+')',backgroundSize:'100% auto'}"></div>
                            </li>
                        </template>
                    </template>
                </ul>
            </main>
            <footer class="footer">
                <input type="text" id="input" placeholder="请输入"/>
                <i class="iconfont icon-tupian" id="imgbtn"></i>
                <button id="send">发送</button>
            </footer>
            <input type="file" accept="image/*" multiple id="uploadInput" style="display: none;" />
        </div>
    </body>
    <script src="/chat/js/jquery-3.3.1.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="/chat/js/iscroll.js" type="text/javascript" charset="utf-8"></script>
    <script src="/chat/js/exif.js" type="text/javascript" charset="utf-8"></script>
    <script src="/chat/js/upload.js" type="text/javascript" charset="utf-8"></script>
    <script src="/chat/js/vue.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="/chat/js/moment.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="/chat/js/moment-with-locales.js" type="text/javascript" charset="utf-8"></script>
    <!-- <script src="/chat/js/vconsole.min.js" type="text/javascript" charset="utf-8"></script> -->
    <!-- 长按撤销 -->
    <script type="text/javascript">
        var timeout, starttime;
        var sendMessageAjaxStatus = false;
        $(function(){
            window.addEventListener('contextmenu', function(e){ e.preventDefault(); });
            $(document).on('click', ".rightbtn", function () {
                var rightbtn = $(this);
                var msgi = rightbtn.data('msgi');
                var msg = app.msgList[msgi];
                sendMessage({event:'recall',to_uid:to_uid,msg_id:msg.id}, function(res){
                    if(res.status){
                        $(".rightbtn").remove();
                        app.msgList.splice(msgi, 1);
                        app.$nextTick(function(){
                            myScroll.refresh();
                        });
                    }
                });
            });
            $(document).on('click', function (e) {
                var right = $(e.target).parent('.right');
                if(right.length > 0){
                    // 点击的是文字或者是图片
                    if(e.target.tagName == 'SPAN' || $(e.target).hasClass('img')){
                        $(".right").not(right[0]).find('.rightbtn').remove();
                    }else{
                        $(".rightbtn").remove();
                    }
                }else{
                    $(".rightbtn").remove();
                }
            });
        });
    </script>
    <script type="text/javascript">
        var user_id = "{$user_id}";
        var user = {:json_encode($user)};
        var to_uid = "{$to_uid}";
        var access_type = "{$access_type}";
        var to_user = {:json_encode($to_user)};
        var last_id = 0;
        var loadingMsgStatus = false;
        var awaitSendSay = [];
        var starttime;
        var jsqT;

        var app = new Vue({
            el:"#app",
            data:{
                msgList:[],
                to_uid:to_uid,
                to_user:to_user,
                user:user,
            },
            methods:{
                onBack: function(){
                    if(window.history.length > 1){
                        window.history.back();
                    }else{
                        wx.closeWindow();
                    }
                },
                timeStr: function(t){
                    moment.locale('zh-cn');
                    // var str = moment(t*1000).format('YYYY年MM月DD日 HH:mm:ss')
                    var str = moment(t*1000).format('LLL')
                    return str;
                },
                rightMsgClick: function(msgI, event){
                    var msg = this.msgList[msgI];
                    if(moment().unix() > parseInt(msg.time)+60*5){
                        return true;
                    }
                    target = event.currentTarget;
                    var left = $(target).find("span").width() / 2 + $(target).find("span").position().left;
                    var top = -35;
                    var html = '<div class="rightbtn" data-msgi="'+msgI+'" style="position:absolute;top:'+top+'px;left:'+left +'px;height:30px;background:#666;border-radius:5px;color:#fff;padding: 0 5px;line-height: 30px;z-index: 2">'+
                        "撤回"+
                        '<div style="width:20px;height:20px;background:#666;position:absolute;transform: rotateZ(45deg);top:11px;z-index: -1;"></div></div>';
                    $(target).append(html);
                },
                rightTouchstart:function(msgI, event){
                    //@touchstart="rightTouchstart(i, $event)" @touchend="rightTouchend($event)"
                    var msg = this.msgList[msgI];
                    if(moment().unix() > parseInt(msg.time)+60*5){
                        return true;
                    }
                    target = event.currentTarget;
                    if($(event.target).hasClass('rightbtn')){
                        return true;
                    }
                    if(jsqT){
                        clearInterval(jsqT);
                    }
                    if(event.target.tagName == 'SPAN' || $(event.target).hasClass('img')){
                        $(".right").not(target).find('.rightbtn').remove();
                    }else{
                        $(".rightbtn").remove();
                    }
                    starttime = new Date();
                    jsqT = setInterval(function(){
                        var currenttime = new Date();
                        // console.log(currenttime - starttime, target);
                        if(currenttime - starttime > 1000){
                            clearInterval(jsqT);
                            jsqT = null;
                            var left = $(target).find("span").width() / 2 + $(target).find("span").position().left;
                            var top = -35;
                            var html = '<div class="rightbtn" data-msgi="'+msgI+'" style="position:absolute;top:'+top+'px;left:'+left +'px;height:30px;background:#666;border-radius:5px;color:#fff;padding: 0 5px;line-height: 30px;z-index: 2">'+
                                "撤回"+
                                '<div style="width:20px;height:20px;background:#666;position:absolute;transform: rotateZ(45deg);top:11px;z-index: -1;"></div></div>';
                            $(target).append(html);
                        }
                    }, 200);
                    return true;
                },
                rightTouchend: function(){
                    if(jsqT){
                        clearInterval(jsqT);
                        jsqT = null;
                    }
                },
                previewImage: function(i){
                    var imgs = [];
                    var current = '';
                    $.each($("#ul .img"), function(index, val) {
                        var $img = $(val);
                        var url = window.location.protocol+'//'+window.location.host+$img.attr('src')+'?t='+index;
                        if($img.data('i') == i){
                            current = url;
                        }
                        imgs.push(url);
                    });
                    wx.previewImage({
                        current: current, // 当前显示图片的http链接
                        urls: imgs // 需要预览的图片http链接列表
                    });
                }
            }
        })
        function sayId() {
            return ''+user_id+(new Date().getTime())+Math.ceil(Math.random()*1000);
        }
        function loadMessage() {
            if(loadingMsgStatus){
                return false;
            }
            loadingMsgStatus = true;
            if(app.msgList.length > 0){
                last_id = app.msgList[0]['id'];
            }else{
                last_id = 0;
            }
            $.ajax({
                url: "{:U('Messages/query')}",
                type: 'POST',
                dataType: 'json',
                data: {to_uid: to_uid, last_id:last_id},
            })
            .done(function(res) {
                // console.log('msg_query', res);
                if(res.status){
                    var indexs = [];
                    $.each(res.list, function(i, item) {
                        item.is_hidden = 1;
                        app.msgList.unshift(item);
                        indexs.push(i);
                    });
                    if(last_id == 0){
                        app.$nextTick(function(){
                            scrollBottom();
                        });
                    }else{
                        if(res.list.length > 0){
                            setTimeout(function(){
                                removeHidden();
                                app.$nextTick(function(){
                                    var height = 0;
                                    var has_num = 0;
                                    for (var i = 0; i < indexs.length * 2 - 1; i++) {
                                        var item = $("#ul li").eq(i);
                                        height+=item.height()+10;
                                        if(item.hasClass('right') || item.hasClass('left')){
                                            has_num++;
                                        }
                                        if(has_num == indexs.length){
                                            break;
                                        }
                                    }
                                    myScroll.refresh();
                                    myScroll.scrollTo(0, -height, 0);
                                })
                            }, 300);
                        }
                    }
                    if(res.list.length > 0){
                        last_id = res.list[res.list.length - 1]['id'];
                    }
                }
            })
            .fail(function() {
                
            })
            .always(function() {
                loadingMsgStatus = false;
            });
        }

        function removeHidden() {
            $.each(app.msgList, function(index, val) {
                 val.is_hidden = 0;
            });
        }

        function scrollBottom() {
            if(myScroll){
                setTimeout(function(){
                    removeHidden();
                    app.$nextTick(function(){
                        myScroll.refresh();
                        maxScrollY = myScroll.maxScrollY;
                        if(!maxScrollY==0){
                            myScroll.scrollTo(0, maxScrollY, 500);
                        }
                    });
                }, 300);
            }
        }

        var ws = null;
        var wsStatus = false;
        var lockReconnect = false;
        var reconnectTime = null;

        function reconnectWs() {
            if(wsStatus || lockReconnect){
                return;
            }
            lockReconnect = true;
            reconnectTime = setInterval(function () {
                createWebSocket();
            }, 3000);
        }
        function createWebSocket() {
            ws = new WebSocket("ws://"+location.host+":7584");
            initEventHandle();
        }
        function initEventHandle() {
            ws.onopen = function(){
                wsStatus = true;
                if(lockReconnect){
                    alert('连接成功');
                }
                lockReconnect = false;
                if(reconnectTime){
                    clearInterval(reconnectTime);
                }
                setInterval(function () {
                    if(wsStatus){
                        var data = {"event":"ping", "say_id":sayId()};
                        // sendMessage(data);
                        // ws.send(JSON.stringify(data));
                        wsSendMsg(data);
                    }
                }, 5000);
            };

            // 服务端主动推送消息时会触发这里的onmessage
            ws.onmessage = function(e){
                // console.log('接收消息', e.data);
                // json数据转换成js对象
                var data = eval("("+e.data+")");
                var event = data.event || '';
                switch(event){
                    // Events.php中返回的init类型的消息，将client_id发给后台进行uid绑定
                    case 'init':
                        // sendMessage({'event':'init', 'uid':user_id});
                        // 利用jquery发起ajax请求，将client_id发给后端进行uid绑定
                        $.post("{:U('bind')}", {client_id: data.client_id, to_uid:to_uid}, function(data){}, 'json');
                        break;
                    case 'say_res':
                        if(!data.status){
                            alert('发送失败');
                        }else{
                            $.each(awaitSendSay, function(i, sayInfo) {
                                 if(sayInfo.say_id == data.say_id){
                                    if(sayInfo.msg_type == 'image'){
                                        app.msgList.push({id:data.msg_id, from_uid:user_id,time:data.time, msg_type:sayInfo.msg_type, content:data.img});
                                    }else{
                                        $("#input").val('');
                                        app.msgList.push({id:data.msg_id, from_uid:user_id,time:data.time, msg_type:sayInfo.msg_type, content:sayInfo.content});
                                    }
                                    awaitSendSay.splice(i, 1);
                                    return false;
                                 }
                            });
                            app.$nextTick(function(){
                                scrollBottom();
                            })
                        }
                        break;
                    case 'msg':
                        if(data.from_uid == to_uid){
                            app.msgList.push({id:data.msg_id, from_uid:data.from_uid,time:data.time, msg_type:data.msg_type, content:data.content, is_hidden:0,avatar:to_user.avatar});
                            var viewH = $('.content').height(), //可见高度
                                contentH = $('.content').get(0).scrollHeight; //内容高度
                            if(myScroll.y*(-1) +$("#ul li").last().height()+30 >  (contentH - viewH)) {
                                app.$nextTick(function(){
                                    scrollBottom();
                                })
                            }else{
                                app.$nextTick(function(){
                                    myScroll.refresh();
                                })
                            }
                        }
                        break;
                    case 'recall':
                        // 对方撤回后的通知
                        if(data.from_uid == to_uid){
                            $.each(app.msgList, function(index, val) {
                                 if(val.id==data.msg_id){
                                    app.msgList.splice(index, 1);
                                    app.$nextTick(function(){
                                        myScroll.refresh();
                                    })
                                 }
                            });
                        }
                        break;
                    case 'pong':
                        break;
                    // 当mvc框架调用GatewayClient发消息时直接alert出来
                    default :
                        alert(e.data);
                }
            };

            ws.onclose = function(evt){
                wsStatus = false;
                console.log('WebSocketClosed!');
                if(!lockReconnect){
                    // 非重连
                    alert('断开连接');
                }
                reconnectWs();
            };

            ws.onerror = function(evt){
                wsStatus = false;
                console.log('WebSocketError!', evt);
                if(!lockReconnect){
                    // 非重连
                    alert('连接失败');
                }
                reconnectWs();
            };
        }
        createWebSocket();

        function sendMessage(data, callback) {
            if(sendMessageAjaxStatus){
                return;
            }
            console.log('post 发送消息', data);
            data['access_type'] = access_type;
            sendMessageAjaxStatus = true;
            // data.say_id = sayId();
            // awaitSendSay.push(data);
            // ws.send(JSON.stringify(data));
            $.ajax({
                url: "{:U('send_msg')}",
                type: 'POST',
                dataType: 'json',
                data: data,
            })
            .done(function(res) {
                if(typeof(callback)!='undefined'){
                    callback(res);
                }
            })
            .fail(function() {
                
            })
            .always(function() {
                sendMessageAjaxStatus = false;
            });
        }

        function wsSendMsg(data) {
            // console.log('ws 发送消息', data);
            data.say_id = sayId();
            ws.send(JSON.stringify(data));
        }

        $(function(){
            $(window).resize(function(event) {
                myScroll.refresh();
                maxScrollY = myScroll.maxScrollY;
                if(!maxScrollY==0){
                    myScroll.scrollTo(0, maxScrollY, 300);
                }                   
            });
            $('#input').blur(function(){
                var dom = this;
                setTimeout(function(){ dom.scrollIntoView(true); },200);
            });
            $('.content').on('click', function(){
                $('#input').blur();
            });
            // var vConsole = new VConsole();
        });
    </script>
    <script type="text/javascript">
        var myScroll = null;
        var maxScrollY = 0;
        $("#imgbtn").click(function(){
            $("#uploadInput").click();
        });
        $("#uploadInput").on("change", function(e){
            var readerFiles = e.target.files[0];
            comImage(readerFiles, function(dat) {
                var img = convertImgDataToBlob(dat);
                var formData = new FormData();
                formData.append("image", img, "file_" + Date.parse(new Date()) + ".png");
                $.ajax({
                    url: "{:U('Upload/upload')}",
                    type: 'POST',
                    dataType: 'json',
                    contentType: false,
                    processData: false,
                    data: formData,
                })
                .done(function(res) {
                    if(res.status){
                        var data = {"event":"say", 'say_id':sayId(), "to_uid":to_uid, 'msg_type':'image', 'content':res.path};
                        awaitSendSay.push(data);
                        sendMessage(data);
                    }else{
                        alert(res.msg);
                    }
                })
                .fail(function() {
                    
                })
                .always(function() {
                    
                });
                $(e.target).val('');
            });
        });
        
        $("#send").click(function(){
            var content = $.trim($("#input").val());
            if(!content){ 
                $("#input").val("");
                $("#input").focus();
                return;
            }
            var data = {"event":"say", 'say_id':sayId(), "to_uid":to_uid, 'msg_type':'text', 'content':content};
            awaitSendSay.push(data);
            $("#input").val("");
            $("#input").focus();
            sendMessage(data);
        });
        
        var _judge = true; 
        
        function iScrollClick(){
            if (/iPhone|iPad|iPod|Macintosh/i.test(navigator.userAgent)) return false;
            if (/Chrome/i.test(navigator.userAgent)) return (/Android/i.test(navigator.userAgent));
            if (/Silk/i.test(navigator.userAgent)) return false;
            if (/Android/i.test(navigator.userAgent)) {
               var s=navigator.userAgent.substr(navigator.userAgent.indexOf('Android')+8,3);
               return parseFloat(s[0]+s[3]) < 44 ? false : true;
            }
        }
        
        window.onload = function(){
            myScroll = new IScroll("#content", {
                click:true,
                scrollbars: true,//有滚动条
                mouseWheel: true,//允许滑轮滚动
                fadeScrollbars: true,//滚动时显示滚动条，默认影藏，并且是淡出淡入效果
                preventDefault: false
            });
            maxScrollY = myScroll.maxScrollY;
            myScroll.refresh();
            myScroll.on('scrollEnd', function () {
                if ( this.y == 0 ) {
                    loadMessage();
                    // do something
                }
            });
            loadMessage();
        };
    </script>
    <script type="text/javascript">
        function resetImg(path, callback) {
            var img = new Image();
            img.onload = function() {
                EXIF.getData(img, function() {
                    var Orientation = EXIF.getTag(this, 'Orientation');
                    setTimeout(function() {
                        if(Orientation != "" && Orientation != 1 && Orientation) {
                            switch(Orientation) {
                                case 6: //需要顺时针（向左）90度旋转  
                                    rotateImgNew(img, 'left', callback);
                                    break;
                                case 8: //需要逆时针（向右）90度旋转  
                                    rotateImgNew(img, 'right', callback);
                                    break;
                                case 3: //需要180度旋转  
                                    var _this = img;
                                    rotateImgNew(img, 'right', function() {
                                        rotateImgNew(_this, 'right', callback);
                                    }); //转两次 
                                    break;
                            }
                        } else {
                            callback(path);
                        }
                    }, 1000);
                });
            };
            img.src = path;
        }
        
        function rotateImgNew(img, direction, callback) {
            var canvas = document.createElement("canvas");
            //最小与最大旋转方向，图片旋转4次后回到原方向    
            var min_step = 0;
            var max_step = 3;
            if(img == null) return;
            //img的高度和宽度不能在img元素隐藏后获取，否则会出错    
            var height = img.height;
            var width = img.width;
            var step = 2;
            if(step == null) {
                step = min_step;
            }
            if(direction == 'right') {
                step++;
                //旋转到原位置，即超过最大值    
                step > max_step && (step = min_step);
            } else {
                step--;
                step < min_step && (step = max_step);
            }
            //旋转角度以弧度值为参数    
            var degree = step * 90 * Math.PI / 180;
            var ctx = canvas.getContext('2d');
            switch(step) {
                case 0:
                    canvas.width = width;
                    canvas.height = height;
                    ctx.drawImage(img, 0, 0);
                    break;
                case 1:
                    canvas.width = height;
                    canvas.height = width;
                    ctx.rotate(degree);
                    ctx.drawImage(img, 0, -height);
                    break;
                case 2:
                    canvas.width = width;
                    canvas.height = height;
                    ctx.rotate(degree);
                    ctx.drawImage(img, -width, -height);
                    break;
                case 3:
                    canvas.width = height;
                    canvas.height = width;
                    ctx.rotate(degree);
                    ctx.drawImage(img, -width, 0);
                    break;
            }
            dat = canvas.toDataURL("image/jpeg", 0.1);
            callback(dat);
        };
        
        function comImage(tdomImg, fn) {
            var fr = new FileReader();
            fr.onload = function(e) {
                var timgdata = e.target.result;
                resetImg(timgdata, function(domImg) {
                    var img = new Image();
                    img.onload = function() {
                        var w0 = img.width;
                        var h0 = img.height;
                        var maxW = 1200;
                        var maxH = 1000;
                        if(maxW < w0 && maxH < h0) {
                            var bl = (maxW / w0) < (maxH / h0) ? maxW / w0 : maxH / h0;
                            var tcan = document.createElement('canvas');
                            tcan.width = w0 * bl;
                            tcan.height = h0 * bl;
                            tctx = tcan.getContext('2d');
                            tctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, tcan.width, tcan.height);
                            fn(tcan.toDataURL("image/jpeg"));
                        } else {
                            fn(timgdata);
                        }
                    };
                    img.src = domImg;
                });
            };
            fr.readAsDataURL(tdomImg);
        }
        function convertImgDataToBlob(base64Data) {
            var format = "image/jpeg";
            var base64 = base64Data;
            var code = window.atob(base64.split(",")[1]);
            var aBuffer = new window.ArrayBuffer(code.length);
            var uBuffer = new window.Uint8Array(aBuffer);
            for(var i = 0; i < code.length; i++) {
                uBuffer[i] = code.charCodeAt(i) & 0xff;
            }
            var blob = null;
            try {
                blob = new Blob([uBuffer], {
                    type: format
                });
            } catch(e) {
                window.BlobBuilder = window.BlobBuilder ||
                    window.WebKitBlobBuilder ||
                    window.MozBlobBuilder ||
                    window.MSBlobBuilder;
                if(e.name == 'TypeError' && window.BlobBuilder) {
                    var bb = new window.BlobBuilder();
                    bb.append(uBuffer.buffer);
                    blob = bb.getBlob("image/jpeg");
        
                } else if(e.name == "InvalidStateError") {
                    blob = new Blob([aBuffer], {
                        type: format
                    });
                } else {
        
                }
            }
            return blob;
        };
    </script>
    <notempty name="js_config">
        <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
        <script type="text/javascript">
            wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
                appId: "{$js_config['appid']}", // 必填，公众号的唯一标识
                timestamp: "{$js_config['timestamp']}", // 必填，生成签名的时间戳
                nonceStr: "{$js_config['noncestr']}", // 必填，生成签名的随机串
                signature: "{$js_config['signature']}",// 必填，签名
                jsApiList: ['previewImage', 'closeWindow'] // 必填，需要使用的JS接口列表
            });
            wx.ready(function(){
                
            });
        </script>
    </notempty>
</html>
